package com.foreveross.fetl.web.action.preprocess;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.foreveross.fetl.common.HBaseTable;
import com.foreveross.fetl.common.hbase.client.HBaseHelper;
import com.foreveross.fetl.common.vo.XiamenReportVO;
import com.foreveross.fetl.common.vo.model.Agent;
import com.foreveross.fetl.common.vo.model.Cabin;
import com.foreveross.fetl.common.vo.model.SinglePlaneInfo;
import com.foreveross.fetl.common.vo.model.Transit;
import com.foreveross.fetl.common.vo.model.doub.CabinRelation;
import com.foreveross.fetl.common.vo.model.doub.DoublePlaneInfo;
import com.foreveross.fetl.common.vo.model.doub.ReturnCabin;
import com.foreveross.fetl.common.vo.model.doub.ReturnDoublePlaneInfo;
import com.foreveross.fetl.common.vo.model.doub.ReturnTransit;
import com.foreveross.fetl.util.DateUtils;
import com.foreveross.fetl.util.HbaseToPlaneInfoUtil;
import com.foreveross.fetl.util.PriceUtil;
import com.foreveross.fetl.util.RowkeyUtils;
import com.foreveross.fetl.web.action.BaseAction;

@Controller("xiamenReportAction")
@Scope("prototype")
public class XiamenReportAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6643572323330893894L;
	
	public String list(){
		return "METHOD";
	}
	
	public String downLoadAll(){
		String start = getRequest().getParameter("start");
		String end = getRequest().getParameter("end");
		List<XiamenReportVO> list =this.findAllDateFromHbase(start,end);
		File file=this.createFile(list,end);
		HttpServletResponse response=getResponse();
		InputStream fis=null;
			try {
				response.reset();
				OutputStream toClient = new BufferedOutputStream(
						response.getOutputStream());
				response.setContentType("application/vnd.ms-excel");
				String filename=null;
				if (getRequest().getHeader("User-Agent").toLowerCase()
						.indexOf("firefox") > 0) {
					filename = new String(file.getName().getBytes("UTF-8"), "ISO8859-1");// firefox浏览器
				} else {
					filename = URLEncoder.encode(file.getName(), "UTF-8");// 其他浏览器
				}
				response.setHeader("Content-Disposition", "attachment; filename="
						+ filename);// 设定输出文件头
				fis = new BufferedInputStream(new FileInputStream(
						file.getPath()));
				byte[] buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				
				toClient.write(buffer);
				toClient.flush();
				toClient.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(null!=file)
					   file.delete();
				
				if(null!=fis){
						try {
							fis.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
			}
		return null;
	}
	
	
	private List<XiamenReportVO> findAllDateFromHbase(String start, String end) {
		final Date startTime=DateUtils.parse(start, "yyyy-MM-dd HH");
		final Date endTime=DateUtils.parse(end, "yyyy-MM-dd HH");
		List<XiamenReportVO> list=new ArrayList<XiamenReportVO>();
		List<Date> flightDates=this.listFlightDate();
		//去哪儿单程直达
		List<String> qunar=this.qunarLine();
		for(String line:qunar){
			for(Date flightDate :flightDates){
				List<XiamenReportVO> listNew=this.findALLOneWayByHbase(line,flightDate,startTime,endTime,"00002","去哪儿",true);
				list.addAll(listNew);
			}
		}
		//Expedia 往返直达和中转
		for(String line:this.listDirectAndTrainsLine()){
			for(Date flightDate :flightDates){
				Calendar c=Calendar.getInstance();
				c.setTime(flightDate);
				c.add(Calendar.DAY_OF_MONTH, 7);
				List<XiamenReportVO> listNew=this.findAllRoundByHbase(line,flightDate,c.getTime(),startTime,endTime,"00010","Expedia");
				list.addAll(listNew);
			}
		}
		for(String line:this.listOnlyTrainsLine()){
			for(Date flightDate :flightDates){
				Calendar c=Calendar.getInstance();
				c.setTime(flightDate);
				c.add(Calendar.DAY_OF_MONTH, 7);
				List<XiamenReportVO> listNew=this.findAllRoundByHbase(line,flightDate,c.getTime(),startTime,endTime,"00010","Expedia");
				list.addAll(listNew);
			}
		}
		return list;
	}

	private List<XiamenReportVO> findAllRoundByHbase(String line,
			Date flightDate, Date returnDate, Date startTime, Date endTime,
			String channel, String channelName) {
			List<XiamenReportVO> list =new ArrayList<XiamenReportVO>();
			Calendar cStart = Calendar.getInstance();
			cStart.setTime(startTime);
			Calendar cEnd = Calendar.getInstance();
			cEnd.setTime(endTime);	
			cEnd.add(Calendar.HOUR_OF_DAY, 1);
			String[] citys=line.split("-");
			while (cStart.before(cEnd)) {
				String startRow=RowkeyUtils.getDoubleRowKey(DateUtils.format(cStart.getTime(), "yyyyMMddHH"), 
						channel, citys[0], citys[1], DateUtils.format(flightDate, "yyyyMMdd"), 
						DateUtils.format(returnDate, "yyyyMMdd"), null, RowkeyUtils.START_ROW_KEY);
				String stopRow=RowkeyUtils.getDoubleRowKey(DateUtils.format(cStart.getTime(), "yyyyMMddHH"), 
						channel, citys[0], citys[1], DateUtils.format(flightDate, "yyyyMMdd"), 
						DateUtils.format(returnDate, "yyyyMMdd"), null, RowkeyUtils.STOP_ROW_KEY);
				ResultScanner rs = null;
				
				try {
					rs = HBaseHelper.getRecords(HBaseTable.BASE_DATA_FLIGHT_DOUBLE, startRow, stopRow);
					for (Result res : rs) {
						try {
							Map<String, Map<String, String>> curMap = HBaseHelper
									.transformHBaseRowToMap(res);
							
							DoublePlaneInfo planeInfo=HbaseToPlaneInfoUtil.hbaseToPlaneInfo(curMap, 1d, DoublePlaneInfo.class);
							if(null==planeInfo || (planeInfo.getTotalLowestPrice()==0 && planeInfo.getSumLowestPrice()==0))
								continue;
							
							XiamenReportVO vo=new XiamenReportVO();
							vo.setChannelName(channelName);
							vo.setFlightDate(DateUtils.format(flightDate, "yyyy-M-d"));
							vo.setLine(line.replace("-", ""));
							vo.setType(planeInfo.getTransits().size()>1?"往返中转":"往返直达");
							
							this.copyByPlaneInfo(vo, planeInfo, planeInfo.getTransits().size()<=1);
							list.add(vo);
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					if(rs != null) rs.close();
					rs = null;
				}
				
				cStart.add(Calendar.HOUR_OF_DAY, 1);
			}
			
		return list;
	}

	private List<XiamenReportVO> findALLOneWayByHbase(String line,
			Date flightDate, Date startTime, Date endTime, String channel,
			String channelName, boolean b) {
		List<XiamenReportVO> list =new ArrayList<XiamenReportVO>();
		Calendar cStart = Calendar.getInstance();
		cStart.setTime(startTime);
		Calendar cEnd = Calendar.getInstance();
		cEnd.setTime(endTime);	
		cEnd.add(Calendar.HOUR_OF_DAY, 1);
		String[] citys=line.split("-");
		while (cStart.before(cEnd)) {
			String startRow=RowkeyUtils.getRowKey(cStart.getTime(), channel, citys[0], citys[1], flightDate, RowkeyUtils.START_ROW_KEY);
			String stopRow=RowkeyUtils.getRowKey(cStart.getTime(), channel, citys[0], citys[1], flightDate, RowkeyUtils.STOP_ROW_KEY);
			ResultScanner rs = null;
			try {
				rs = HBaseHelper.getRecords(HBaseTable.BASE_DATA_FLIGHT, startRow, stopRow);
				for (Result res : rs) {
					try {
						Map<String, Map<String, String>> curMap = HBaseHelper
								.transformHBaseRowToMap(res);
						
						SinglePlaneInfo singlePlaneInfo=HbaseToPlaneInfoUtil.hbaseToSinglePlaneInfo(curMap,1d,SinglePlaneInfo.class);
						
						if(null==singlePlaneInfo || (singlePlaneInfo.getTotalLowestPrice()==0 && singlePlaneInfo.getSumLowestPrice()==0 ))
							continue;
						if(b && singlePlaneInfo.getTransits().size()>1){
							continue;
						}
						XiamenReportVO vo=new XiamenReportVO();
						vo.setChannelName(channelName);
						vo.setFlightDate(DateUtils.format(flightDate, "yyyy-M-d"));
						vo.setLine(line.replace("-", ""));
						vo.setType(b?"单程直达":"单程中转");
						this.copyByPlaneInfo(vo, singlePlaneInfo);
						list.add(vo);
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(rs != null) rs.close();
				rs = null;
			}
			cStart.add(Calendar.HOUR_OF_DAY, 1);
		}
		return list;
	}

	public String downLoad(){
		String start = getRequest().getParameter("start");
		String end = getRequest().getParameter("end");
		List<XiamenReportVO> list =this.findDateFromHbase(start,end);
		File file=this.createFile(list,end);
		HttpServletResponse response=getResponse();
		InputStream fis=null;
			try {
				response.reset();
				OutputStream toClient = new BufferedOutputStream(
						response.getOutputStream());
				response.setContentType("application/vnd.ms-excel");
				String filename=null;
				if (getRequest().getHeader("User-Agent").toLowerCase()
						.indexOf("firefox") > 0) {
					filename = new String(file.getName().getBytes("UTF-8"), "ISO8859-1");// firefox浏览器
				} else {
					filename = URLEncoder.encode(file.getName(), "UTF-8");// 其他浏览器
				}
				response.setHeader("Content-Disposition", "attachment; filename="
						+ filename);// 设定输出文件头
				fis = new BufferedInputStream(new FileInputStream(
						file.getPath()));
				byte[] buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				
				toClient.write(buffer);
				toClient.flush();
				toClient.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(null!=file)
					   file.delete();
				
				if(null!=fis){
						try {
							fis.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
			}
		return null;
	}
	
	private File createFile(List<XiamenReportVO> list, String time) {
		String fileName="xiamen_"+time.replace(" ", "").replace("-", "")+".xlsx";
		XSSFWorkbook  workbook = null;
		OutputStream os = null;
		InputStream fis=null;
		File file=null;
		try {
			workbook = new XSSFWorkbook();
			XSSFSheet sheet = workbook.createSheet(DateUtils.format(new Date(), "yyyy-MM-dd HHmm"));
			
			String[] title ={"来源","航线","航班号","航班日期","最低票价","票价货币","票价类型","相应订座舱位","供应商","采集时间"};
			XSSFRow row = sheet.createRow(0);
	        for(int i=0;i<title.length;i++){
	        	XSSFCell cell = row.createCell(i);
	        	cell.setCellValue(title[i]);
	        }
	        
	        int column=1;
	        XSSFRow   rows =null;
	        XSSFCell cell=null;
	        for(XiamenReportVO vo:list){
	        	rows = sheet.createRow(column);
	        	int i=0;
	        	cell=rows.createCell(i++);
				cell.setCellValue(vo.getChannelName());
				
				cell=rows.createCell(i++);
				cell.setCellValue(vo.getLine());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getFlightNo()?"NA":vo.getFlightNo());
				
				cell=rows.createCell(i++);
				cell.setCellValue(vo.getFlightDate());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getPrice()?0:vo.getPrice());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getCurrency()?"NA":vo.getCurrency());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getType()?"NA":vo.getType());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getCabin()?"NA":vo.getCabin());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getAgengtName()?"NA":vo.getAgengtName());
				
				cell=rows.createCell(i++);
				cell.setCellValue(null==vo.getGrabDate()?"NA":vo.getGrabDate());
				 column++;
	        }
	        if(null==file || !file.exists()){
	        	 file=new File(fileName);
	        }
	        os = new FileOutputStream(file); 
	        workbook.write(os);
	        os.close();
	        os=null;
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			
			if(null!=os){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null!=fis){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return file;
	}

	private List<XiamenReportVO> findDateFromHbase(String start, String end) {
		final Date startTime=DateUtils.parse(start, "yyyy-MM-dd HH");
		final Date endTime=DateUtils.parse(end, "yyyy-MM-dd HH");
		List<XiamenReportVO> list=new ArrayList<XiamenReportVO>();
		List<Date> flightDates=this.listFlightDate();
		//去哪儿单程直达
		List<String> qunar=this.qunarLine();
		for(String line:qunar){
			for(Date flightDate :flightDates){
				XiamenReportVO vo=this.findOneWayByHbase(line,flightDate,startTime,endTime,"00002","去哪儿",true);
				list.add(vo);
			}
		}
		//Expedia 往返直达和中转
		for(String line:this.listDirectAndTrainsLine()){
			for(Date flightDate :flightDates){
				Calendar c=Calendar.getInstance();
				c.setTime(flightDate);
				c.add(Calendar.DAY_OF_MONTH, 7);
				XiamenReportVO vo=this.findRoundByHbase(line,flightDate,c.getTime(),startTime,endTime,"00010","Expedia",true);
				list.add(vo);
				list.add(this.findRoundByHbase(line,flightDate,c.getTime(),startTime,endTime,"00010","Expedia",false));
			}
		}
		for(String line:this.listOnlyTrainsLine()){
			for(Date flightDate :flightDates){
				Calendar c=Calendar.getInstance();
				c.setTime(flightDate);
				c.add(Calendar.DAY_OF_MONTH, 7);
				XiamenReportVO vo=this.findRoundByHbase(line,flightDate,c.getTime(),startTime,endTime,"00010","Expedia",false);
				list.add(vo);
			}
		}
		return list;
	}
	
	
	
	private XiamenReportVO findRoundByHbase(String line, Date flightDate,
			Date returnDate, Date startTime, Date endTime,String channel,String channelName, boolean b) {
		XiamenReportVO vo=new XiamenReportVO();
		vo.setChannelName(channelName);
		vo.setFlightDate(DateUtils.format(flightDate, "yyyy-M-d"));
		vo.setLine(line.replace("-", ""));
		vo.setType(b?"往返直达":"往返中转");
		
		Calendar cStart = Calendar.getInstance();
		cStart.setTime(startTime);
		Calendar cEnd = Calendar.getInstance();
		cEnd.setTime(endTime);	
		cEnd.add(Calendar.HOUR_OF_DAY, 1);
		String[] citys=line.split("-");
		DoublePlaneInfo lowerPlanInfo=null;
		Double price=0d;
		while (cStart.before(cEnd)) {
			String startRow=RowkeyUtils.getDoubleRowKey(DateUtils.format(cStart.getTime(), "yyyyMMddHH"), 
					channel, citys[0], citys[1], DateUtils.format(flightDate, "yyyyMMdd"), 
					DateUtils.format(returnDate, "yyyyMMdd"), null, RowkeyUtils.START_ROW_KEY);
			String stopRow=RowkeyUtils.getDoubleRowKey(DateUtils.format(cStart.getTime(), "yyyyMMddHH"), 
					channel, citys[0], citys[1], DateUtils.format(flightDate, "yyyyMMdd"), 
					DateUtils.format(returnDate, "yyyyMMdd"), null, RowkeyUtils.STOP_ROW_KEY);
			ResultScanner rs = null;
			
			try {
				rs = HBaseHelper.getRecords(HBaseTable.BASE_DATA_FLIGHT_DOUBLE, startRow, stopRow);
				for (Result res : rs) {
					try {
						Map<String, Map<String, String>> curMap = HBaseHelper
								.transformHBaseRowToMap(res);
						
						DoublePlaneInfo planeInfo=HbaseToPlaneInfoUtil.hbaseToPlaneInfo(curMap, 1d, DoublePlaneInfo.class);
						if(null==planeInfo || (planeInfo.getTotalLowestPrice()==0 && planeInfo.getSumLowestPrice()==0))
							continue;
						if(b && planeInfo.getTransits().size()>1){
							continue;
						}
						if(this.compare(price,planeInfo)){
							lowerPlanInfo=planeInfo;
							price=planeInfo.getTotalLowestPrice();
							if(null==price || price==0){
								price=planeInfo.getSumLowestPrice();
							}
						}
							
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(rs != null) rs.close();
				rs = null;
			}
			
			cStart.add(Calendar.HOUR_OF_DAY, 1);
		}
		if(null!=lowerPlanInfo)
			this.copyByPlaneInfo(vo, lowerPlanInfo, b);
		else
			System.out.println(line+DateUtils.format(flightDate, "yyyy-M-d")+" null");
		return vo;
	}
	

	private boolean compare(Double price, DoublePlaneInfo planeInfo) {
		
		Double newPrice=planeInfo.getTotalLowestPrice();
		if(null==newPrice || newPrice==0){
			newPrice=planeInfo.getSumLowestPrice();
		}
		if(null==newPrice || newPrice==0)
			return false;
		if(price==0)
			return true;
		if(price>newPrice)
			return true;
		return false;
	}

	private void copyByPlaneInfo(XiamenReportVO vo, DoublePlaneInfo planeInfo,boolean b) {
		try {
			boolean isSumPrice=false;
			Double price=planeInfo.getTotalLowestPrice();
			if(null==price || price==0){
				price=planeInfo.getSumLowestPrice();
				isSumPrice=true;
			}
			vo.setPrice(PriceUtil.round(price, 2, BigDecimal.ROUND_HALF_DOWN));
			vo.setCurrency(null==planeInfo.getCurrency()?"CNY":planeInfo.getCurrency());
			vo.setGrabDate(DateUtils.format(planeInfo.getGrabDate(), "yyyy-M-d/HHmm"));
			CabinRelation cabinRelation =null;
			for(CabinRelation relation:planeInfo.getCabinRelations()){
				Double relationPrice=relation.getFullPrice();
				if(isSumPrice){
					relationPrice=relation.getTotalFullPrice();
				}
				if(price==relationPrice){
					cabinRelation=relation;
					break;
				}
			}
			
//			ReturnDoublePlaneInfo returnPlane=null;
//			ReturnCabin returnCabin=null;
//			for(ReturnDoublePlaneInfo returnVo:planeInfo.getReturnPlaneInfos()){
//				if(null!=cabinRelation){
//					for(ReturnCabin c:returnVo.getReturnCabins()){
//						if(cabinRelation.getReturnCabinId().equals(c.getId())){
//							returnPlane=returnVo;
//							returnCabin=c;
//							break;
//						}
//					}
//					if(null!=returnPlane)
//						break;
//				}else{
//					double returnPrice=returnVo.getTotalLowestPrice();
//					if(isSumPrice)
//						returnPrice=returnVo.getSumLowestPrice();
//					if(price==returnPrice){
//						returnPlane=returnVo;
//						break;
//					}
//				}
//				
//			}
//			
//			if(null==returnPlane)
//				for(ReturnDoublePlaneInfo returnVo:planeInfo.getReturnPlaneInfos()){
//					double returnPrice=returnVo.getTotalLowestPrice();
//					if(isSumPrice)
//						returnPrice=returnVo.getSumLowestPrice();
//					if(price==returnPrice){
//						returnPlane=returnVo;
//						break;
//					}
//				}
//			if(null==returnCabin && null!=returnPlane){
//				for(ReturnCabin c:returnPlane.getReturnCabins()){
//					double returncabinPrice=c.getPrice();
//					if(isSumPrice)
//						returncabinPrice=c.getOriginalPrice();
//					if(returncabinPrice==price){
//						returnCabin=c;
//						break;
//					}
//				}
//			}
				
			
			StringBuffer flightNo=new StringBuffer();
			StringBuffer cabinName=new StringBuffer();
			//直飞
			
				
			if(b){
				if(null!=planeInfo.getTransits() && planeInfo.getTransits().size()==1){
					cabinName.append(planeInfo.getTransits().get(0).getCabinName());
				}
				if(cabinName.length()==0 && null!=planeInfo.getCabins()){
					for(Cabin cabin:planeInfo.getCabins()){
						if(cabin.getId().equals(cabinRelation.getCabinId())){
							cabinName.append(cabin.getSubCabinName());
						}
					}
				}
//				if(null!=returnCabin)
//					cabinName.append("-").append(returnCabin.getSubCabinName());
				
				flightNo.append(appendFlightNo(planeInfo.getFlightNo()));
//				if(null!=returnPlane)
//				flightNo.append(appendFlightNo(returnPlane.getFlightNo()));
			}else{
				for(Transit transit:planeInfo.getTransits()){
					flightNo.append(appendFlightNo(transit.getFlightNo())).append("-");
					cabinName.append(transit.getCabinName()).append("-");
				}
				
				if(flightNo.toString().endsWith("-"));
					flightNo.delete(flightNo.length()-1, flightNo.length());
				if(cabinName.toString().endsWith("-"))
					cabinName.delete(cabinName.length()-1, cabinName.length());
//				cabinName.append("-");
//				
//				if(null!=returnPlane)
//					for(ReturnTransit retransit:returnPlane.getReturnTransits()){
//						flightNo.append(appendFlightNo(retransit.getFlightNo()));
//						cabinName.append(retransit.getCabinName());
//					}
			}
			
			  if(null!=planeInfo.getAgents()){
						  for(Agent agent:planeInfo.getAgents()){
							  double agentPrice=agent.getPrice();
							  if(agentPrice==0)
								  agentPrice=agent.getOriginalPrice();
							  if(0==agentPrice)
								  continue;
							  
							  if(price==agentPrice){
								  vo.setAgengtName(null!=agent.getName()?agent.getName():agent.getCompanyName());
							  }
						  }
			  }
			  vo.setCabin(cabinName.toString());
			  vo.setFlightNo(flightNo.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	private XiamenReportVO findOneWayByHbase(String line, Date flightDate,
			Date startTime, Date endTime,String channel,String channelName, boolean b) {
		XiamenReportVO vo=new XiamenReportVO();
		vo.setChannelName(channelName);
		vo.setFlightDate(DateUtils.format(flightDate, "yyyy-M-d"));
		vo.setLine(line.replace("-", ""));
		vo.setType(b?"单程直达":"单程中转");
		
		Calendar cStart = Calendar.getInstance();
		cStart.setTime(startTime);
		Calendar cEnd = Calendar.getInstance();
		cEnd.setTime(endTime);	
		cEnd.add(Calendar.HOUR_OF_DAY, 1);
		String[] citys=line.split("-");
		SinglePlaneInfo lowerPlane=null;
		Double price=0d;
		while (cStart.before(cEnd)) {
			String startRow=RowkeyUtils.getRowKey(cStart.getTime(), channel, citys[0], citys[1], flightDate, RowkeyUtils.START_ROW_KEY);
			String stopRow=RowkeyUtils.getRowKey(cStart.getTime(), channel, citys[0], citys[1], flightDate, RowkeyUtils.STOP_ROW_KEY);
			ResultScanner rs = null;
			try {
				rs = HBaseHelper.getRecords(HBaseTable.BASE_DATA_FLIGHT, startRow, stopRow);
				for (Result res : rs) {
					try {
						Map<String, Map<String, String>> curMap = HBaseHelper
								.transformHBaseRowToMap(res);
						
						SinglePlaneInfo singlePlaneInfo=HbaseToPlaneInfoUtil.hbaseToSinglePlaneInfo(curMap,1d,SinglePlaneInfo.class);
						
						if(null==singlePlaneInfo || (singlePlaneInfo.getTotalLowestPrice()==0 && singlePlaneInfo.getSumLowestPrice()==0 ))
							continue;
						if(b && singlePlaneInfo.getTransits().size()>1){
							continue;
						}
						if(this.compare(price,singlePlaneInfo)){
							lowerPlane=singlePlaneInfo;
							price=singlePlaneInfo.getTotalLowestPrice();
							if(null==price|| price==0){
								price=singlePlaneInfo.getSumLowestPrice();
							}
						}
							
						
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(rs != null) rs.close();
				rs = null;
			}
			cStart.add(Calendar.HOUR_OF_DAY, 1);
		}
		if(null!=lowerPlane)
			this.copyByPlaneInfo(vo, lowerPlane);
		return vo;
	}

	private boolean compare(Double price, SinglePlaneInfo singlePlaneInfo) {
		Double newPrice=singlePlaneInfo.getTotalLowestPrice();
		if(newPrice==0)
			newPrice=singlePlaneInfo.getSumLowestPrice();
		if(price==0){
			return true;
		}else if(price>newPrice){
			return true;
		}
		return false;
		
	}

	private void copyByPlaneInfo(XiamenReportVO vo,
			SinglePlaneInfo planeInfo) {
			try {
				Double price=planeInfo.getTotalLowestPrice();
				if(price==0)
					price=planeInfo.getSumLowestPrice();
				vo.setPrice(PriceUtil.round(price, 2, BigDecimal.ROUND_HALF_DOWN));
				vo.setCurrency(null==planeInfo.getCurrency()?"CNY":planeInfo.getCurrency());
				vo.setFlightNo(appendFlightNo(planeInfo.getFlightNo()));
				vo.setGrabDate(DateUtils.format(planeInfo.getGrabDate(), "yyyy-M-d/HHmm"));
				
				for(Cabin cabin:planeInfo.getCabins()){
						if(null==cabin.getPrice())
							continue;
						if(price.intValue()==cabin.getPrice().intValue() && null!=cabin.getSubCabinName()){
							vo.setCabin(cabin.getSubCabinName());
							break;
						}
							
					}
				
				  
					for(Agent agent:planeInfo.getAgents()){
						if(null==agent.getPrice())
						continue;
						if(price.intValue()==agent.getPrice().intValue()){
						 vo.setAgengtName(null!=agent.getName()?agent.getName():agent.getCompanyName());
						}
					}
				  
			} catch (Exception e) {
				e.printStackTrace();
			}
		
		
	}

	/**
	 * 去哪儿
	 * @return
	 */
	private List<String> qunarLine(){
		List<String> lines = Arrays.asList("SHA-PEK", "PEK-SHA", "SZX-SHA",
				"CAN-HGH", "HGH-CAN", "SHA-SZX", "HGH-PEK", "PEK-HGH",
				"HGH-SZX", "SZX-HGH", "XMN-SHA", "SHA-XMN", "PEK-XMN",
				"XMN-PEK", "XIY-XNN", "XIY-URC", "XNN-XIY", "PEK-CSX",
				"CSX-PEK", "INC-XIY", "URC-XIY", "KMG-HGH", "HGH-KMG",
				"XIY-INC", "HGH-CTU", "CTU-HGH", "CKG-LXA", "CGO-URC",
				"LXA-CKG", "URC-CGO", "WUH-KMG", "KMG-WUH", "HGH-CGO",
				"CGO-HGH", "CKG-XIY", "DLC-TAO", "XIY-CKG", "TAO-HRB",
				"TAO-DLC", "XMN-CSX", "CSX-XMN", "CAN-XMN", "HRB-TAO",
				"XMN-CAN", "XIY-XMN", "XMN-XIY", "CKG-HGH", "HGH-CKG",
				"HAK-PEK", "PEK-HAK");
		return lines;
	}
	
	
	
	/**
	 * 航班日期
	 * @return
	 */
	private List<Date> listFlightDate(){
		List<Date> list =new ArrayList<Date>();
		Date d =DateUtils.parse("2014-09-15", "yyyy-MM-dd");
		list.add(d);
		Calendar c =Calendar.getInstance();
		c.setTime(d);
		for(int i=0;i<6;i++){
			c.add(Calendar.DAY_OF_MONTH, 1);
			list.add(c.getTime());
		}
		return list;
	}
	
	/**
	 * 渠道Expedia 直达和中转
	 * @return
	 */
	private List<String> listDirectAndTrainsLine(){
		List<String> lines = Arrays.asList("XMN-SIN", "SIN-XMN", "XMN-BKK",
				"JKT-XMN");
		return lines;
	}
	
	/**
	 *  渠道 Expedia 的中转
	 * @return
	 */
	private List<String> listOnlyTrainsLine(){
		return  Arrays.asList("XMN-HKT","XMN-DPS");
	}
	
	private String appendFlightNo(String flightNo){
		if(flightNo == null)
			return "NA";
		if(flightNo.length()>=6)
			return flightNo;
		if(!flightNo.matches("[0-9]{0,1}[A-Z]{1,2}\\d+"))
			return flightNo;
		StringBuilder build=new StringBuilder(flightNo);
		build.insert(2, "0");
		return appendFlightNo(build.toString());
		
	}

}
